package com.iap.report.mediator
{
	import com.iap.app.AppGlobal;
	import com.iap.app.AppText;
	import com.iap.client.event.MainEvent;
	import com.iap.client.view.control.ClientButton;
	import com.iap.common.AppSession;
	import com.iap.common.event.FavoriteEvent;
	import com.iap.common.event.InstanceEvent;
	import com.iap.common.event.InstanceFavoriteEvent;
	import com.iap.common.event.ReportEvent;
	import com.iap.common.mediator.BaseMediator;
	import com.iap.common.model.Favorite;
	import com.iap.common.model.Instance;
	import com.iap.common.model.InstanceFavorite;
	import com.iap.common.model.Report;
	import com.iap.common.signal.FavoriteRequestSignal;
	import com.iap.common.signal.InstanceFavoriteRequestSignal;
	import com.iap.common.signal.InstanceRequestSignal;
	import com.iap.common.view.control.FavoriteDisplay;
	import com.iap.report.signal.ReportRequestSignal;
	import com.iap.report.view.ReportView;
	import com.iap.report.view.control.PDFExportButton;
	import com.iap.report.view.favorite.FavoriteReportView;
	
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.html.HTMLLoader;
	import flash.html.HTMLPDFCapability;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ArrayList;
	
	import org.alivepdf.display.Display;
	import org.alivepdf.drawing.Blend;
	import org.alivepdf.images.ImageFormat;
	import org.alivepdf.layout.Layout;
	import org.alivepdf.layout.Mode;
	import org.alivepdf.layout.Orientation;
	import org.alivepdf.layout.Position;
	import org.alivepdf.layout.Resize;
	import org.alivepdf.layout.Size;
	import org.alivepdf.layout.Unit;
	import org.alivepdf.pdf.PDF;
	import org.alivepdf.saving.Method;
	
	import spark.events.IndexChangeEvent;
	import spark.events.TextOperationEvent;

	public class ReportMediator extends BaseMediator
	{
		[Inject]
		public var view:ReportView;
		[Inject]
		public var instanceRequest:InstanceRequestSignal;
		[Inject]
		public var reportRequest:ReportRequestSignal;
		
		private var model:Report = new Report();
		
		private var readyCount:int = 0;
		
		private var pageSizeData:ArrayCollection;
		private var pageOrientationData:ArrayCollection;
		
		private var favoriteData:Array;
		
		override public function onRegister():void
		{
			addContextListener(InstanceEvent.RESPONSE, instanceResponseHandler);
			addContextListener(ReportEvent.RESPONSE, reportResponseHandler);
			addViewListener(MouseEvent.CLICK, handleMouseClick);
			dispatchRequest();
		}
		
		private function dispatchRequest():void
		{
			AppGlobal.startWait();
			instanceRequest.dispatch(AppSession.currentInstance, InstanceRequestSignal.GET);
		}

		private function handleMouseClick(evt:MouseEvent):void
		{
			var propertyName:String = "name";
			var btnName:String = "";
			if(evt.target.hasOwnProperty(propertyName))
			{
				btnName = evt.target[propertyName];
			}
			if(btnName == PDFExportButton.NAME)
			{
				initExportReport();
			}
			if(btnName == ClientButton.NAME)
			{
				dispatch(new MainEvent(MainEvent.SELECT_CLIENT));
			}
		}

		private function instanceResponseHandler(evt:InstanceEvent):void
		{
			AppGlobal.endWait();
			if(evt.response.task == InstanceRequestSignal.GET)
			{
				var instance:Instance = evt.response.result as Instance;
				favoriteData = instance.favorites;
				view.favoriteDisplay.dataProvider = new ArrayCollection(favoriteData);
				if(instance.report != null)
				{
					model = instance.report;
				}
			}
			readyCount = view.favoriteDisplay.dataProvider.length;
			initializeView();
		}
		
		private function initializeView():void
		{
			view.favoriteDisplay.addEventListener(FavoriteDisplay.EVENT_READY, readyFavoriteHandler);

			pageOrientationData = new ArrayCollection();
			pageOrientationData.addItem({key:Report.PAGE_ORIENTATION_LANDSCAPE, value:AppText.PAGE_LANDSCAPE});
			pageOrientationData.addItem({key:Report.PAGE_ORIENTATION_PORTRAIT, value:AppText.PAGE_PORTRAIT});
			view.pageOrientationData = pageOrientationData;
			view.pageOrientationForm.selectedIndex = 0;

			pageSizeData = new ArrayCollection()
			pageSizeData.addItem({key:Report.PAGE_SIZE_LEGAL, value:AppText.PAGE_SIZE_LEGAL});
			pageSizeData.addItem({key:Report.PAGE_SIZE_A4, value:AppText.PAGE_SIZE_A4});
			pageSizeData.addItem({key:Report.PAGE_SIZE_LETTER, value:AppText.PAGE_SIZE_LETTER});
			view.pageSizeData = pageSizeData;
			view.pageSizeForm.selectedIndex = 0;
			
			view.reportTitleForm.addEventListener(TextOperationEvent.CHANGE, changeReportTitleHander);
			view.pageOrientationForm.addEventListener(Event.CHANGE, changePageOrientationHandler);
			view.pageSizeForm.addEventListener(Event.CHANGE, changePageSizeHandler);
			
			view.gapyForm.addEventListener(Event.CHANGE, changeGapyHandler);
			view.gapxForm.addEventListener(Event.CHANGE, changeGapxHandler);
			view.imageSizeForm.addEventListener(Event.CHANGE, changeImageSizeHandler);
			
			setControlFromModel();
		}
		
		private function setControlFromModel():void
		{
			if(model.id == 0) return;
			view.reportTitleForm.text = model.title;
			view.reportTitleDisplay.text = view.reportTitleForm.text;
			var i:uint
			for(i = 0; i<pageOrientationData.length; i++)
			{
				if(pageOrientationData[i].key == model.pageOrientation)
				{
					view.pageOrientationForm.selectedIndex = i;
				}
			}
			for(i = 0; i<pageSizeData.length; i++)
			{
				if(pageSizeData[i].key == model.pageSize)
				{
					view.pageSizeForm.selectedIndex = i;
				}
			}
			view.gapxForm.value = model.gapX;
			view.gapyForm.value = model.gapY;
			view.imageSizeForm.value = model.imageSize == 0 ? 500 : model.imageSize;
			setGapxDisplay();
			setGapyDisplay();
			setImageSizeDisplay();
		}
		
		private function changeGapxHandler(evt:Event):void
		{
			setGapxDisplay();
		}

		private function changeImageSizeHandler(evt:Event):void
		{
			setImageSizeDisplay();
			setGapxDisplay();
			setGapyDisplay();
		}
		
		private function setGapxDisplay():void
		{
			var defaultColWidth:int = model.imageSize > FavoriteReportView.DEFAULT_TILE_COLUMNWIDTH ? model.imageSize : FavoriteReportView.DEFAULT_TILE_COLUMNWIDTH;
			var colWidth:int = defaultColWidth + (view.gapxForm.value*10);
			view.favoriteDisplay.tileLayout.columnWidth = colWidth;
			model.gapX = view.gapxForm.value;
		}
		
		private function changeGapyHandler(evt:Event):void
		{
			setGapyDisplay();
		}
		
		private function setImageSizeDisplay():void
		{
			model.imageSize = view.imageSizeForm.value;
			for each(var item:Favorite in favoriteData)
			{
				item.imageSize = model.imageSize;
			}
			view.favoriteDisplay.dataProvider = new ArrayCollection(favoriteData);
		}
		
		private function setGapyDisplay():void
		{
			var defaultRowHeight:int = model.imageSize > FavoriteReportView.DEFAULT_TILE_ROWHEIGHT ? model.imageSize : FavoriteReportView.DEFAULT_TILE_ROWHEIGHT;
			var rowHeight:int = defaultRowHeight + (view.gapyForm.value*10);
			view.favoriteDisplay.tileLayout.rowHeight = rowHeight;
			model.gapY = view.gapyForm.value;
		}
		
		private function changePageOrientationHandler(evt:IndexChangeEvent):void
		{
			model.pageOrientation = view.pageOrientationForm.dataProvider[evt.newIndex].key;
		}
		
		private function changePageSizeHandler(evt:IndexChangeEvent):void
		{
			model.pageSize = view.pageSizeForm.dataProvider[evt.newIndex].key;
		}
		
		private function readyFavoriteHandler(evt:Event):void
		{
			readyCount--;
			if(readyCount<=0)
			{
				view.favoriteDisplay.removeEventListener(FavoriteDisplay.EVENT_READY, readyFavoriteHandler);
				view.pdfExportBtn.enabled = true;
			}
		}

		private function setPageSize():Size
		{
			var pageSize:Size = Size.A4;
			switch(model.pageSize)
			{
				case Report.PAGE_SIZE_LEGAL:
				{
					pageSize = Size.LEGAL;
					break;
				}
				case Report.PAGE_SIZE_A4:
				{
					pageSize = Size.A4;
					break;
				}
				case Report.PAGE_SIZE_LETTER:
				{
					pageSize = Size.LETTER;
					break;
				}
				default:
				{
					pageSize = Size.LEGAL;
					break;
				}
			}
			return pageSize;
		}
		
		private function initExportReport():void
		{
			saveReport();
			var pageOrientation:String = model.pageOrientation == Report.PAGE_ORIENTATION_LANDSCAPE ? Orientation.LANDSCAPE : Orientation.PORTRAIT;
			var pageSize:Size = setPageSize();
			
			var pdf:PDF = new PDF(pageOrientation, Unit.MM, pageSize);
			pdf.setDisplayMode(Display.FULL_WIDTH, Layout.SINGLE_PAGE, Mode.FIT_TO_PAGE);
			pdf.addPage();
			var resize:Resize = new Resize(Mode.FIT_TO_PAGE, Position.LEFT);
			
			pdf.addImage(view.reportDisplay, resize, 0, 0, 0, 0, 0, 1, true, ImageFormat.PNG, 100);
			
			var pdfFile:File = savePDF(pdf);
			pdfFile.openWithDefaultApplication();
		}
		
		private function savePDF(pdf:PDF):File
		{
			var fileStream:FileStream = new FileStream();
			var file:File = File.createTempDirectory();
			file = file.resolvePath(AppGlobal.REPORT_FAVORITE_PDF_NAME);
			fileStream.open(file, FileMode.WRITE);
			var bytes:ByteArray = pdf.save(Method.LOCAL);
			fileStream.writeBytes(bytes);
			fileStream.close();
			return file;
		}
		
		private function openPDF(pdfpath:String):void
		{
			var htmlLoader:HTMLLoader = new HTMLLoader();
			htmlLoader.x = 0;
			htmlLoader.y = 0;
			htmlLoader.width = view.stage.stageWidth;
			htmlLoader.height = view.stage.stageHeight;
			if(HTMLLoader.isSupported &&
				(HTMLLoader.pdfCapability == HTMLPDFCapability.STATUS_OK))
			{
				htmlLoader.load(new URLRequest(pdfpath));
			} else
			{
				htmlLoader.loadString("handle errors in user friendly way");
			};
		}

		private function changeReportTitleHander(evt:Event):void
		{
			view.reportTitleDisplay.text = view.reportTitleForm.text;
			model.title = view.reportTitleForm.text;
		}
		
		private function saveReport():void
		{
			if(model.id > 0)
			{
				reportRequest.dispatch(model, ReportRequestSignal.SAVE);
			}
		}

		private function reportResponseHandler(evt:ReportEvent):void
		{
			AppGlobal.endWait();
			if(evt.response.task == ReportRequestSignal.GET)
			{
			}
		}
	}
}